/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

/*!
 * \file pack_cfour.h
 * \brief defines the package of applications to link with Cfour
 * \author G.Reinisch
 */
#ifndef PACKCFOUR
#define PACKCFOUR

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <msTreeMapper.h>
#include <msZMat.h>

namespace atomism
{

class qcCfour : public msTreeMapper
{     
private:
//!\name from msRegister 
//@{
      static msRegistrar Registrar;
      static bool        isCfourRegisteredInPython;
      static msRegister* createInstance() { return new qcCfour; }
//@}   
      double* I2d;

protected:

      void registryInPython();

public:
      
      void initialize(){ msTreeMapper::initialize();
			 declareAttribute( BasisSet,"BasisSet");
	 		 declareAttribute( CiType  ,"CiType");
	 		 declareAttribute( WorkingDirectory  ,"WorkingDirectory");
	 		 declareAttribute( GenBasSymLink  ,"GenBasSymLink" );
                         }

      void update(){ msTreeMapper::update();
		     }

      static boost::shared_ptr<qcCfour> New() { boost::shared_ptr<qcCfour> T( new qcCfour );
	       				        T->initialize();
	       				        T->update();
	       					return T;
	       					}

      virtual boost::shared_ptr<msTreeMapper> clone() { boost::shared_ptr<qcCfour> clone = New(); 
	    					        clone->msTreeMapper::operator=(*this);					      
	    					        return clone;
            					        } 

     static const string BASISSET_NAMES[];
     static const string CITYPE_NAMES[];

     enum qcBasisSet
       {
	G6_31,	
	G6_311,
	ANO0,
	ANO1,
	ANO2,
	AUG_PVDZ,
        AUG_PVTZ,
        AUG_PVQZ,
	AUG_PCVDZ,
        AUG_PCVTZ,
        AUG_PCVQZ
        };        
 
     enum qcCiType
       {
	HF,	
	MP2,
	MP4,
	CCSD,
	CCSDpT,
	CCSDT
        };
  
      qcCfour() : msTreeMapper() { constructVar("qcCfour","Cfour","cfour");BasisSet="AUG-PVDZ";CiType="CCSD";
				   WorkingDirectory="./Cfour";
				   };
      
      boost::shared_ptr<msTreeMapper> setLevel(qcBasisSet bs, qcCiType CI);

      boost::shared_ptr<msTreeMapper> setWorkingDirectory(std::string dir);

      boost::shared_ptr<msTreeMapper> setGenBasSymLink(std::string link);

      double singlePoint( const msZMat& zmt);
      double singlePoint();
      
      void writeInput( const msZMat& zmt);
      
      //double optimize( const msZMat& zmt, string frozen);

      bool TestXaces2();
      
private:

      void cleanDir();
      double getEnergy(string file);
  
      std::string BasisSet;
      std::string WorkingDirectory;	
      std::string CiType;
      std::string GenBasSymLink;
      };
 

}
#endif
